/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package PacketHandling;

import Client.Client;
import com.esotericsoftware.kryo.Kryo;
import com.esotericsoftware.kryonet.Connection;
import com.esotericsoftware.kryonet.Listener;
import com.esotericsoftware.kryonet.Server;
import horizon.entity.Entity;
import horizon.network.EntityEncoder;
import horizon.network.NetChunk;
import horizon.network.Packet;
import horizon.network.Packet.PKT_TYPE;
import horizon.util.Vector2;
import java.io.IOException;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Queue;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author J_Laptop
 */
public class PacketHandler {

    long lastUpdateTime;
    Server server;
    Queue<Packet> packets = new LinkedList<Packet>();
    Packet movementUpdate = new Packet();
    static int guestID = 1;
    public ArrayList<Client> clients = new ArrayList<>();
    private static PacketHandler instance;

    public static PacketHandler getInstance() {
        return instance;
    }

    public PacketHandler() {

        server = new Server();
        server.start();

        Kryo kryo = server.getKryo();

        kryo.register(NetChunk.class);
        kryo.register(Packet.class);
        kryo.register(Packet.PKT_TYPE.class);
        kryo.register(byte[].class);

        try {
            server.bind(54555, 54777);
        } catch (IOException ex) {
            Logger.getLogger(PacketHandler.class.getName()).log(Level.INFO, null, ex);
        }



        server.addListener(new Listener() {

            @Override
            public void received(Connection connection, Object object) {

                if (object instanceof Packet) {
                    Packet request = (Packet) object;

                    PacketParser parse = new PacketParser(request, connection);

                }
            }
        });

        instance = this;
    }

    private void addPacketToQueue(Packet p) {

        packets.offer(p);

    }

    public Server getServer() {
        return server;
    }

    public void sendQueuedPackets() {

        packets.offer(movementUpdate);

        int s = packets.size();

        while (packets.size() > 0) {
            Packet p = packets.remove();
            p.sendTime = System.currentTimeMillis();

            server.sendToAllTCP(p);

        }
        lastUpdateTime = System.currentTimeMillis();
        if (s > 0) {
            //System.out.println(s + " packets sent this batch at: " + lastUpdateTime);
        }
        movementUpdate = new Packet();

    }

    public void addMovementUpdate(String name, Vector2 currentPos, Vector2 move) {

        if (movementUpdate._data.length() > 2000) {
            //sendQueuedPackets();
        } else {
            movementUpdate._data += "mov:" + name + ":" + currentPos + ":" + move + ";";
        }


    }

    public void sendEntityList(Connection c, ArrayList<Entity> entities) {
        Packet p = new Packet();
        p.header = PKT_TYPE.SERV_MAPDATA;
        p._data += "entityList;";

        for (Entity entity : entities) {


            p._data += EntityEncoder.createString(entity);

        }
        p.sendTime = System.currentTimeMillis();
        server.sendToTCP(c.getID(), p);
    }

    public void sendNewEntity(Entity e , Connection c) {

        Packet p = new Packet();
        p.header = PKT_TYPE.SERV_MAPDATA;
        p._data += "entity;";
        p._data += EntityEncoder.createString(e);
        p.sendTime = System.currentTimeMillis();
        server.sendToAllExceptTCP(c.getID(), p);

    }

    public void sendPacketNumber(Connection c, int n) {

        Packet p = new Packet();
        p.header = PKT_TYPE.SERV_MAPDATA;
        p._data += "packetNumber;" + n + ";";
        p.sendTime = System.currentTimeMillis();

        server.sendToTCP(c.getID(), p);

    }

    public void sendChunk(Connection c, NetChunk chunk) {

        server.sendToTCP(c.getID(), chunk);

    }
    
    public void sendChat(int id , String s){
        
        Packet p = new Packet();
        p.header = PKT_TYPE.SERV_DATA;
        p._data += "cha:" + s;
        p.sendTime = System.currentTimeMillis();

        server.sendToTCP(id, p);
        
    }
}
